use super::{
    err, err_value, json, ok, throw_err, Base, Client, ECode, Fbf, Lock, Resp, SvCache, VBase,
    VMap, Value,
};
use reqwest::header::{HeaderMap, HeaderValue, CONTENT_TYPE};

pub struct Tech;

impl Base for Tech {}

impl Tech {
    pub async fn do_cmd(&self, cmd: &str, cache: SvCache, lock: Lock, client: &Client) -> Resp {
        let reader = Fbf;

        match cmd {
            "list" => {
                let _ = lock.lock().await;

                let body = reader.get_file("file", "setting", &cache)?;
                let body = body.ck_obj("set")?;

                let ip = body.ck_str("ip")?;
                let line = body.ck_str("line")?;

                let mut head = HeaderMap::new();
                head.insert(CONTENT_TYPE, self.to_head("application/json")?);

                let cmd = json!({
                    "line": line
                });

                let data = cmd.to_string();
                let url = format!("http://{ip}/cfgdb/tech/list");

                if let Ok(body_tech) = client.send_http(&data, &url, 1000, head).await {
                    let body_tech = body_tech.ck_array("data")?;
                    let body_tech = json!(body_tech);

                    let _ = reader.write("file", "tech", &body_tech, &cache).await?;
                }

                let body = reader.get_file("file", "tech", &cache)?;
                let body = body.ckarray()?;

                ok!(body)
            }
            _ => throw_err!(ECode::NoServe, "no file serve"),
        }
    }

    fn to_head(&self, val: &str) -> Result<HeaderValue, Value> {
        HeaderValue::from_str(val).or_else(|e| err!(ECode::Post, e))
    }
}
